package com.arvin.faceDetect.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.google.mlkit.vision.face.Face

/**
 * 人脸检测结果的叠加显示视图
 * 负责在相机预览上绘制人脸检测框
 */
class FaceOverlayVie人脸检测前后端摄像头眼睛追踪正常版 @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 绘制人脸框的画笔
    private val paint = Paint().apply {
        color = Color.GREEN      // 框的颜色为绿色
        style = Paint.Style.STROKE  // 绘制空心矩形
        strokeWidth = 3f         // 减小线条宽度
        isAntiAlias = true      // 启用抗锯齿
    }

    // 当前检测到的人脸列表
    private var faces: List<Face> = emptyList()

    // 预览视图的尺寸
    private var previewWidth = 0
    private var previewHeight = 0

    // 原始图像的尺寸
    private var imageWidth = 0
    private var imageHeight = 0

    // 是否使用前置相机
    private var isFrontCamera = true

    // 图像旋转角度
    private var imageRotation = 0

    // 坐标转换矩阵
    private var transformationMatrix = Matrix()

    // 是否需要更新转换矩阵
    private var needUpdateTransformation = true

    // 是否显示人脸框
    private var showFaceRect = true

    // 是否显示眼睛框
    private var showEyeRect = true

    /**
     * 设置是否显示人脸追踪框
     */
    fun setShowFaceRect(show: Boolean) {
        showFaceRect = show
        invalidate()
    }

    /**
     * 设置是否显示眼睛追踪框
     */
    fun setShowEyeRect(show: Boolean) {
        showEyeRect = show
        invalidate()
    }

    /**
     * 更新人脸检测结果
     * @param faces 检测到的人脸列表
     * @param showFaceRect 是否显示人脸框
     * @param imageWidth 原始图像宽度
     * @param imageHeight 原始图像高度
     * @param rotation 图像旋转角度
     * @param isFrontCamera 是否是前置相机
     */
    fun updateFaces(
        faces: List<Face>,
        showFaceRect: Boolean,
        imageWidth: Int,
        imageHeight: Int,
        rotation: Int,
        isFrontCamera: Boolean = true,
        showEyeRect: Boolean = true
    ) {
        this.faces = faces
        this.showFaceRect = showFaceRect
        this.imageWidth = imageWidth
        this.imageHeight = imageHeight
        this.imageRotation = rotation
        this.isFrontCamera = isFrontCamera
        this.showEyeRect = showEyeRect
        needUpdateTransformation = true
        invalidate()
    }

    /**
     * 更新坐标转换矩阵
     * 将原始图像坐标系(720x720)转换为预览视图坐标系(1080x1100)
     */
    private fun updateTransformationIfNeeded() {
        if (!needUpdateTransformation) return

        // 重置变换矩阵，确保从初始状态开始转换
        transformationMatrix.reset()

        // 计算缩放比例
        // scaleX = 1080/720 = 1.5
        // scaleY = 1100/720 ≈ 1.53
        val scaleX = width.toFloat() / imageWidth.toFloat()
        val scaleY = height.toFloat() / imageHeight.toFloat()
        // 使用较小的缩放比例(1.5)以保持图像比例，避免拉伸
        val scale = minOf(scaleX, scaleY)

        // Log.d("FaceOverlayView", """
        //     开始计算变换矩阵：
        //     预览视图尺寸: ${width}x${height}
        //     图像尺寸: ${imageWidth}x${imageHeight}
        //     比例: $scaleX vs $scaleY
        // """.trimIndent())

        // 创建测试矩形(0,0,720,720)用于跟踪转换效果
        val testRect = RectF(0f, 0f, imageWidth.toFloat(), imageHeight.toFloat())
        // Log.d("FaceOverlayView", "原始矩形: $testRect")

        // 计算居中偏移量
        // dx = (1080 - 720*1.5)/2 = 0
        // dy = (1100 - 720*1.5)/2 = 10
        val dx = (width - imageWidth * scale) / 2f
        val dy = (height - imageHeight * scale) / 2f
        // Log.d("FaceOverlayView", """
        //     计算变换参数:
        //     缩放比例: scale=$scale (scaleX=$scaleX, scaleY=$scaleY)
        //     偏移量: dx=$dx, dy=$dy
        // """.trimIndent())

        // 1. 先进行整体缩放(1.5倍)
        // 720x720 -> 1080x1080
        transformationMatrix.postScale(scale, scale)
        testRect.set(0f, 0f, imageWidth * scale, imageHeight * scale)
        // Log.d("FaceOverlayView", "步骤1-缩放后: $testRect")

        // 2. 将图像移动到预览视图中心
        // 上下各留出10像素边距
        transformationMatrix.postTranslate(dx, dy)
        testRect.offset(dx, dy)
        // Log.d("FaceOverlayView", "步骤2-平移后: $testRect")

        // 3. 前置相机需要水平镜像
        // 以预览视图中心(540,550)为轴进行镜像
        if (isFrontCamera) {
            transformationMatrix.postScale(-1f, 1f, width / 2f, height / 2f)
            val centerX = width / 2f
            testRect.set(
                centerX - (testRect.right - centerX),  // 镜像后的左边界
                testRect.top,                          // 保持垂直位置不变
                centerX + (centerX - testRect.left),   // 镜像后的右边界
                testRect.bottom                        // 保持垂直位置不变
            )
            // Log.d("FaceOverlayView", "步骤3-镜像后: $testRect")
        }

        // Log.d("FaceOverlayView", """
        //     最终变换结果:
        //     偏移量: dx=$dx, dy=$dy
        //     最终矩形: $testRect
        // """.trimIndent())

        needUpdateTransformation = false
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) {
            needUpdateTransformation = true  // 视图大小改变时需要更新变换矩阵
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (!showFaceRect || faces.isEmpty() || previewWidth == 0 || previewHeight == 0) return

        // 更新转换矩阵
        if (needUpdateTransformation) {
            transformationMatrix.reset()

            // 计算缩放比例
            val scaleX =
                previewWidth.toFloat() / (if (imageRotation % 180 == 0) imageWidth else imageHeight)
            val scaleY =
                previewHeight.toFloat() / (if (imageRotation % 180 == 0) imageHeight else imageWidth)

            // 根据相机类型和旋转角度设置变换
            if (isFrontCamera) {
                // 前置摄像头
                transformationMatrix.postScale(scaleX, scaleY)
                if (imageRotation == 90) {
                    transformationMatrix.postRotate(90f, previewWidth / 2f, previewHeight / 2f)
                } else if (imageRotation == 270) {
                    transformationMatrix.postRotate(270f, previewWidth / 2f, previewHeight / 2f)
                }
            } else {
                // 后置摄像头
                transformationMatrix.postScale(scaleX, scaleY)
                if (imageRotation == 90) {
                    transformationMatrix.postRotate(270f, previewWidth / 2f, previewHeight / 2f)
                } else if (imageRotation == 270) {
                    transformationMatrix.postRotate(90f, previewWidth / 2f, previewHeight / 2f)
                }
            }

            needUpdateTransformation = false
        }

        // 绘制人脸框
        for (face in faces) {
            val box = face.boundingBox
            val rect = RectF(box)
            transformationMatrix.mapRect(rect)
            canvas.drawRect(rect, paint)
        }
    }

    /**
     * 绘制眼睛检测框
     */
    private fun drawEyeRect(canvas: Canvas, face: Face) {
        val leftEye = face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.LEFT_EYE)?.position
        val rightEye =
            face.getLandmark(com.google.mlkit.vision.face.FaceLandmark.RIGHT_EYE)?.position
        if (leftEye != null && rightEye != null) {
            // 计算两眼之间的距离
            val eyeDistance = Math.hypot(
                (rightEye.x - leftEye.x).toDouble(),
                (rightEye.y - leftEye.y).toDouble()
            ).toFloat()

            // 根据人脸旋转角度调整眼睛区域大小
            val rotationY = Math.abs(face.headEulerAngleY)
            val eyeScale = if (rotationY > 30) 0.4f else if (rotationY > 15) 0.3f else 0.2f
            // 创建包含两只眼睛的矩形区域
            val eyeRegion = RectF(
                Math.min(leftEye.x, rightEye.x) - eyeDistance * eyeScale,  // 左边界
                Math.min(leftEye.y, rightEye.y) - eyeDistance * eyeScale,  // 上边界
                Math.max(leftEye.x, rightEye.x) + eyeDistance * eyeScale,  // 右边界
                Math.max(leftEye.y, rightEye.y) + eyeDistance * eyeScale   // 下边界
            ).apply {
                // 确保眼睛区域在图像范围内
                left = left.coerceIn(0f, imageWidth.toFloat())
                top = top.coerceIn(0f, imageHeight.toFloat())
                right = right.coerceIn(0f, imageWidth.toFloat())
                bottom = bottom.coerceIn(0f, imageHeight.toFloat())
            }

            // Log.d("FaceOverlayView", """
            //     眼睛区域:
            //     左眼: $leftEye
            //     右眼: $rightEye
            //     眼距: $eyeDistance
            //     边界: $eyeRegion
            // """.trimIndent())

            // 转换并绘制眼睛区域
            val transformedEyeRegion = RectF(eyeRegion)
            transformationMatrix.mapRect(transformedEyeRegion)
            canvas.drawRect(transformedEyeRegion, paint)
        }
    }

    /**
     * 设置预览视图尺寸
     * @param width 预览视图宽度
     * @param height 预览视图高度
     */
    fun setPreviewSize(width: Int, height: Int) {
        previewWidth = width
        previewHeight = height
        needUpdateTransformation = true  // 预览尺寸改变时需要更新变换矩阵
        invalidate()
    }
} 